package com.caipos.actor.shared;

import com.caipos.actor.ActorSystemContext;
import com.caipos.actor.common.actors.KbActorCtx;
import com.caipos.actor.common.data.constant.ComponentLifecycleState;
import com.caipos.actor.common.data.id.EntityId;
import com.caipos.actor.common.data.id.TenantId;
import com.caipos.actor.common.msg.KbMsg;
import com.caipos.actor.tenant.TenantProfileConfiguration;
import com.caipos.util.RuleNodeException;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public abstract class ComponentMsgProcessor<T extends EntityId> extends AbstractContextAwareMsgProcessor {

    protected final TenantId tenantId;
    protected final T entityId;
    protected ComponentLifecycleState state;

    protected ComponentMsgProcessor(ActorSystemContext systemContext, TenantId tenantId, T id) {
        super(systemContext);
        this.tenantId = tenantId;
        this.entityId = id;
    }


    public abstract String getComponentName();

    public abstract void start(KbActorCtx context) throws Exception;

    public abstract void stop(KbActorCtx context) throws Exception;


    public void onCreated(KbActorCtx context) throws Exception {
        start(context);
    }

    public void onUpdate(KbActorCtx context) throws Exception {
        restart(context);
    }

    public void onActivate(KbActorCtx context) throws Exception {
        restart(context);
    }

    public void onSuspend(KbActorCtx context) throws Exception {
        stop(context);
    }

    public void onStop(KbActorCtx context) throws Exception {
        stop(context);
    }

    private void restart(KbActorCtx context) throws Exception {
        stop(context);
        start(context);
    }

    protected void checkComponentStateActive(KbMsg tbMsg) throws RuleNodeException {
        if (state != ComponentLifecycleState.ACTIVE ) {
            log.debug("Component is not active. Current state [{}] for processor [{}][{}] tenant [{}]", state, entityId.getEntityType(), entityId, tenantId);
            RuleNodeException ruleNodeException = getInactiveException();
            if (tbMsg != null) {
                tbMsg.getCallback().onFailure(ruleNodeException);
            }
            throw ruleNodeException;
        }
    }

    protected TenantProfileConfiguration getTenantProfileConfiguration() {
        return systemContext.getTenantProfileCache().get(tenantId).getProfileData().getConfiguration();
    }

    abstract protected RuleNodeException getInactiveException();

}
